package com.cyc.basic.service.poi.impl;

/**
 * @description:
 * @author chenyc
 * @date 2023/4/18 15:02
 */

import com.alibaba.excel.annotation.ExcelProperty;
import com.cyc.basic.pojo.dto.NoSatisfyDto;
import com.cyc.basic.pojo.dto.ZjUserDto;
import com.cyc.basic.pojo.poi.UserWorkRecord;
import com.cyc.basic.pojo.poi.UserWorkCommonPlan;
import com.cyc.basic.pojo.poi.enums.EnumNoSatisfyReason;
import com.cyc.basic.service.poi.IPoiService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PoiServiceImpl implements IPoiService {


    private static SimpleDateFormat df = new SimpleDateFormat("HH:mm");
    private static List<String> FILE_NAME = Arrays.asList("userName", "type", "dept", "number", "jobTitle", "userId");

    private static Date RIGHT_BEGIN_A;
    private static Date RIGHT_END_A;
    private static Date RIGHT_BEGIN_B;
    private static Date RIGHT_END_B;
    private static Date MIDDLE_DATE_A;
    private static Date MIDDLE_DATE_B;


    static {
        try {
            RIGHT_BEGIN_A = df.parse("7:30");
            RIGHT_END_A = df.parse("17:00");
            RIGHT_BEGIN_B = df.parse("13:00");
            RIGHT_END_B = df.parse("21:00");
            MIDDLE_DATE_A = df.parse("12:00");
            MIDDLE_DATE_B = df.parse("17:00");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<ZjUserDto> analyseData(List<UserWorkRecord> userWorkRecordList, List<UserWorkCommonPlan> userWorkCommonPlanList) throws IllegalAccessException, ParseException, NoSuchFieldException {

        Map<String, UserWorkCommonPlan> userNameAndPlanMap =
                userWorkCommonPlanList.stream().collect(Collectors.toMap(UserWorkCommonPlan::getUserName, plan -> plan, (k1, k2) -> k1));
        List<ZjUserDto> zjUserDtoList = new ArrayList<>();
        for (UserWorkRecord userWorkRecord : userWorkRecordList) {
            if (userWorkRecord == null) {
                continue;
            }
            // 过滤未加入考勤的人
            if ("未加入考勤组".equals(userWorkRecord.getType())) {
                continue;
            }
            ZjUserDto zjUserDto = new ZjUserDto();
            List<String> notSatisfyDayList = new ArrayList<>();
            List<NoSatisfyDto> notSatisfyDtoList = new ArrayList<>();
            UserWorkCommonPlan userWorkCommonPlan = userNameAndPlanMap.get(userWorkRecord.getUserName());
            if (userWorkCommonPlan == null) {
                System.out.println("姓名: " + userWorkRecord.getUserName() + "没有考勤计划");
            }
            for (Field field : userWorkRecord.getClass().getDeclaredFields()) {
                // 注解上的值
                String annotationName = field.getAnnotation(ExcelProperty.class).value()[0];
                // 字段名
                String fieldName = field.getName();
                if (FILE_NAME.contains(fieldName)) {
                    continue;
                }
                field.setAccessible(Boolean.TRUE);
                // 字段值
                Object fileValue = field.get(userWorkRecord);
                // 获取指定日期的考勤计划
                Object planObject = "A";
                if (userWorkCommonPlan == null) {
                    System.out.println("姓名: " + userWorkRecord.getUserName() + "在" + annotationName + "号" + "没有考勤计划");
                } else {
                    Field planFiled = userWorkCommonPlan.getClass().getDeclaredField(fieldName);
                    planFiled.setAccessible(Boolean.TRUE);
                    planObject = planFiled.get(userWorkCommonPlan);
                }
//                List<String> satisfy = this.getNotSatisfyList(annotationName, fileValue, planObject);
//                if (CollectionUtils.isEmpty(satisfy)) {
//                    continue;
//                }
                zjUserDto.setUserName(userWorkRecord.getUserName());
//                notSatisfyDayList.addAll(satisfy);
                NoSatisfyDto notSatisfyDto = this.getNotSatisfyDto(annotationName, fileValue, planObject);
                if (notSatisfyDto == null) {
                    continue;
                }
                if (notSatisfyDto.getNoSatisfyReason() != null) {
                    notSatisfyDto.setNoSatisfyReasonName(notSatisfyDto.getNoSatisfyReason().getDesc());
                }
                notSatisfyDtoList.add(notSatisfyDto);
            }
//            if (CollectionUtils.isEmpty(notSatisfyDayList)) {
//                continue;
//            }
            if (CollectionUtils.isEmpty(notSatisfyDtoList)) {
                continue;
            }
            zjUserDto.setNotSatisfyDayList(notSatisfyDayList);
            zjUserDto.setNoSatisfyDtoList(notSatisfyDtoList);
            zjUserDtoList.add(zjUserDto);
        }
        return zjUserDtoList;
    }

    private List<String> getNotSatisfyList(String day, Object obj, Object planObject) throws ParseException {
        // 当天没有考勤计划, 过滤即可, 0表示休息
        if (planObject == null || "0".equals(planObject.toString())) {
            return null;
        }
        // 考勤计划
        String planType = planObject.toString();
        Date beginWorkDate = "A".equals(planType) ? RIGHT_BEGIN_A : RIGHT_BEGIN_B;
        Date endWorkDate = "A".equals(planType) ? RIGHT_END_A : RIGHT_END_B;
        Date middleDate = "A".equals(planType) ? MIDDLE_DATE_A : MIDDLE_DATE_B;

        List<String> notSatisfyList = new ArrayList<>();
        if (obj == null) {
            notSatisfyList.add(day + ", 没有考勤记录");
            return notSatisfyList;
        }
        String data = obj.toString();
        // 当天没打卡
        if (StringUtils.isBlank(data)) {
            notSatisfyList.add(day + ", 没有打卡");
            return notSatisfyList;
        }
        data = data.replace(" ", "");
        String[] split = data.trim().split("\n");
        List<String> list = new ArrayList<>(Arrays.asList(split));

        // 如果只有一条, 说明没打上班卡, 或者没打下班卡
        int dakaCnt = list.size();
//        if (dakaCnt == 1) {
//            String daKaTime = list.get(0);
//            // 继续判断是上班或下班没打卡
//            Date dakaDate = df.parse(daKaTime);
//            if (dakaDate.after(middleDate)) {
//                // 上班打卡了
//                notSatisfyList.add(day + "号, 上班没有打卡, 打卡时间: " + daKaTime);
//                return notSatisfyList;
//            } else {
//                notSatisfyList.add(day + "号, 下班没有打卡, 打卡时间: " + daKaTime);
//                return notSatisfyList;
//            }
//        }

        String begin = list.get(0);
        String end = list.get(dakaCnt - 1);
        Date beginDate = df.parse(begin);
        Date endDate = df.parse(end);
        // 上班没打卡
        if (beginDate.after(middleDate)) {
            notSatisfyList.add(day + "号, 上班没有打卡, 打卡时间: " + list);
            return notSatisfyList;
        } else {
            // 上班迟到
            if (beginDate.after(beginWorkDate)) {
                notSatisfyList.add(day + "号, 上班迟到, 打卡时间: " + list);
                return notSatisfyList;
            }
        }
        // 下班没有打卡
        if (endDate.before(middleDate)) {
            notSatisfyList.add(day + "号, 下班没有打卡, 打卡时间: " + list);
            return notSatisfyList;
        } else {
            // 下班早退
            if (endDate.before(endWorkDate)) {
                notSatisfyList.add(day + "号, 下班早退, 打卡时间: " + list);
                return notSatisfyList;
            }
        }
        return notSatisfyList;
    }

    private NoSatisfyDto getNotSatisfyDto(String day, Object workRecordObj, Object planObject) throws ParseException {
        NoSatisfyDto noSatisfyDto = new NoSatisfyDto();
        // 当天没有考勤计划, 过滤即可, 0表示休息
        if (planObject == null || "0".equals(planObject.toString())) {
            return null;
        }
        // 考勤计划
        String planType = planObject.toString();
        Date beginWorkDate = "A".equals(planType) ? RIGHT_BEGIN_A : RIGHT_BEGIN_B;
        Date endWorkDate = "A".equals(planType) ? RIGHT_END_A : RIGHT_END_B;
        Date middleDate = "A".equals(planType) ? MIDDLE_DATE_A : MIDDLE_DATE_B;

        noSatisfyDto.setDay(day);
        if (workRecordObj == null) {
            noSatisfyDto.setNoSatisfyReason(EnumNoSatisfyReason.NO_WORK_RECORD);
            return noSatisfyDto;
        }
        String workRecord = workRecordObj.toString();
        if (StringUtils.isBlank(workRecord)) {
            noSatisfyDto.setNoSatisfyReason(EnumNoSatisfyReason.NO_WORK_RECORD);
            return noSatisfyDto;
        }
        workRecord = workRecord.replace(" ", "");
        String[] split = workRecord.trim().split("\n");
        List<String> workRecordList = new ArrayList<>(Arrays.asList(split));
        noSatisfyDto.setWorkRecord(workRecordList);

        // 如果只有一条, 说明没打上班卡, 或者没打下班卡
        int dakaCnt = workRecordList.size();
        String begin = workRecordList.get(0);
        String end = workRecordList.get(dakaCnt - 1);
        Date beginDate = df.parse(begin);
        Date endDate = df.parse(end);
        // 上班没打卡
        if (beginDate.after(middleDate)) {
            noSatisfyDto.setNoSatisfyReason(EnumNoSatisfyReason.NO_BEGIN_RECORD);
            return noSatisfyDto;
        } else {
            // 上班迟到
            if (beginDate.after(beginWorkDate)) {
                noSatisfyDto.setNoSatisfyReason(EnumNoSatisfyReason.BEGIN_BE_LATE);
                return noSatisfyDto;
            }
        }
        // 下班没有打卡
        if (endDate.before(middleDate)) {
            noSatisfyDto.setNoSatisfyReason(EnumNoSatisfyReason.NO_END_RECORD);
            return noSatisfyDto;
        } else {
            // 下班早退
            if (endDate.before(endWorkDate)) {
                noSatisfyDto.setNoSatisfyReason(EnumNoSatisfyReason.END_LEAVE_EARLY);
                return noSatisfyDto;
            }
        }
        return null;
    }

}
